package ee.karileet.productcatalogue.dao.impl;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.SimpleExpression;

/**
 * @author Markus Karileet
 * @version 1.0
 * @created 29-nov-2013 16:12:54
 */
public class GenericHome {
	protected String entityName;
	protected final SessionFactory sessionFactory = getSessionFactory();
	private static final Log log = LogFactory.getLog(GenericHome.class);
	
	public GenericHome(String entity){
		this.entityName = entity;
	}
	
	protected SessionFactory getSessionFactory() {
		try {
			return new Configuration().configure().buildSessionFactory();
		} catch (Exception e) {
			log.error("Could not locate SessionFactory in JNDI", e);
			throw new IllegalStateException(
					"Could not locate SessionFactory in JNDI");
		}
	}
	
	public void save(Object o) {
		Session ses = sessionFactory.openSession();
		ses.beginTransaction();
		ses.save(o);
		ses.getTransaction().commit();
	}
	
	/**
	 * 
	 * @exception Throwable
	 */
	public void finalize()
	  throws Throwable{

	}
	
	/**
	 * 
	 * @param entityName    entityName
	 */
	public List<?> findAll(String entityName) throws RuntimeException {
		log.debug("selecting all " + entityName);
		try {
			Session session = sessionFactory.openSession();
			session.beginTransaction();
			Criteria criteria = session.createCriteria(entityName);
			criteria.addOrder(Order.desc("id"));
			log.debug("select successful");
			return criteria.list();
		} catch (RuntimeException re) {
			log.error("select failed", re);
			throw re;
		}
	}

	/**
	 * 
	 * @param expressions
	 * @param entityName    entityName
	 */
	public List<?> find(String entityName, List<SimpleExpression> expressions) throws RuntimeException {
		log.debug("selecting by criteria " + entityName);
		try {
			Session session = sessionFactory.openSession();
			session.beginTransaction();
			Criteria criteria = session.createCriteria(entityName);
			for (Object exp : expressions) {
				criteria.add((Criterion) exp);
			}
			criteria.addOrder(Order.desc("id"));
			log.debug("select successful");
			return criteria.list();
		} catch (RuntimeException re) {
			log.error("select failed", re);
			throw re;
		}
	}

}